#include "protocolhandler.h"
#include <QBitArray>
ProtocolHandler::ProtocolHandler(QObject *parent)
    : QObject{parent}
{

}

//验证控制类命令输入的合法性
bool ProtocolHandler::validateMessageFormat(const QByteArray &data)
{
    qDebug() << "刚进入验证控制的data: " << data.toHex();

    // 验证每个字节是否为16进制数
    QRegExp hexRegExp("^[0-9A-Fa-f]+$");
    if (!hexRegExp.exactMatch(data.toHex())) {  // 转换为16进制字符串并检查
        QMessageBox::warning(nullptr, "校验错误", "数据包含非16进制字符。");
        return false;
    }

    // 计算CRC校验码
    QByteArray messageContent = data.mid(0, 6); // 获取前6字节用于CRC校验
    unsigned short calculatedCRC = calculateCRC(messageContent);
    // 以小端形式提取接收到的CRC校验码
    unsigned short receivedCRC = static_cast<unsigned short>(
        (static_cast<unsigned char>(data[7]) << 8) | // 高字节
        static_cast<unsigned char>(data[6])        // 低字节
        );

    qDebug() << "验证后的data: " << data.toHex();
    qDebug() << "Calculated CRC: " << QString::number(calculatedCRC, 16);
    qDebug() << "Received CRC: " << QString::number(receivedCRC, 16);

    if (calculatedCRC != receivedCRC) {
        QMessageBox::warning(nullptr, "校验错误", "CRC校验失败。");
        return false;
    }

    return true;  // 所有检查均通过
}
//计算CRC
unsigned short ProtocolHandler::calculateCRC(const QByteArray &data)
{


    unsigned short crc = 0xFFFF; // 初始值
    unsigned short poly = 0xA001; // 多项式

    for (quint8 byte : data) {
        // 输入反转
        quint8 reversedByte = 0;
        for (int i = 0; i < 8; i++) {
            reversedByte = (reversedByte << 1) | ((byte >> (7 - i)) & 1);
        }

        crc ^= reversedByte;
        for (int i = 0; i < 8; i++) {
            if (crc & 0x0001) {
                crc = (crc >> 1) ^ poly;
            } else {
                crc >>= 1;
            }

        }
    }

    // 输出反转
    unsigned short reversedCrc = 0;
    for (int i = 0; i < 16; i++) {
        reversedCrc = (reversedCrc << 1) | ((crc >> (15 - i)) & 1);
    }

    return reversedCrc;
}
// CRC公有接口函数
unsigned short ProtocolHandler::publicCalculateCRC(const  QByteArray &data)
{
    return calculateCRC(data);
}
//...................................
//分包函数
QList<QByteArray> ProtocolHandler::createPackets(quint8 station, quint8 sid, quint8 count, const QByteArray &data)
{
    QList<QByteArray> packets; // 存储生成的包
    quint32 extendedLinearAddress = 0x00000000; // 存储当前的扩展线性地址
    QByteArray currentData; // 临时存储当前地址的数据
    quint32 currentAddress = 0x00000000; // 临时存储当前地址

    // 创建QBuffer对象并设置数据
    QBuffer buffer;
    buffer.setData(data);
    buffer.open(QIODevice::ReadOnly);

    QTextStream stream(&buffer);
    QString line;

    // 读取文件内容，逐行解析
    while (stream.readLineInto(&line)) {
        if (line.startsWith(':') && line.length() >= 11) {
            int byteCount = line.midRef(1, 2).toInt(nullptr, 16);
            int address = line.midRef(3, 4).toInt(nullptr, 16);
            int recordType = line.midRef(7, 2).toInt(nullptr, 16);

            quint32 fullAddress = (extendedLinearAddress & 0xFFFF0000) | address;

            if (recordType == 0x04) {
                if (byteCount == 2) {
                    extendedLinearAddress = (quint32(line.midRef(9, 2).toInt(nullptr, 16) << 24)) | (quint32(line.midRef(11, 2).toInt(nullptr, 16) << 16));
                    qInfo() << "解析到扩展线性地址记录，地址: " << extendedLinearAddress;

                    if (!currentData.isEmpty()) {
                        addressDataMap[currentAddress & 0xFFFF0000] = currentData;
                        currentData.clear();
                    }
                    currentAddress = (extendedLinearAddress & 0xFFFF0000) | address;
                } else {
                    qCritical() << "无效的扩展线性地址记录，该记录的字节长度应为2，实际为" << byteCount;
                }
            } else if (recordType == 0x00) {
                qInfo() << "解析到数据记录，完整地址: " << fullAddress;

                // 获取数据部分
                QByteArray parsedData = parseHexLine(line, extendedLinearAddress);

                // 检查地址是否连贯
                if (currentAddress + (currentData.size() / 2) < fullAddress) {
                    int paddingSize = (fullAddress - currentAddress - (currentData.size() / 2)) * 2;
                    currentData.append(QByteArray(paddingSize, 0xFF));
                }

                // 合并数据
                currentData.append(parsedData);
                currentAddress = fullAddress + byteCount;
            } else if (recordType == 0x01) {
                qInfo() << "解析到结束记录";
                if (!currentData.isEmpty()) {
                    addressDataMap[currentAddress & 0xFFFF0000] = currentData;
                }
                break;
            }
        } else {
            qCritical() << "无效的hex行: " << line;
        }
    }

    buffer.close();

    // 生成数据包
    generatePacketsFromSegment(station, sid, count, addressDataMap, packets);

    return packets;
}

//解析.Hex文件 行 的函数
QByteArray ProtocolHandler::parseHexLine(const QString &hexLine, quint32 &extendedLinearAddress)
{
    if (hexLine.startsWith(':') && hexLine.length() >= 11) {
        int byteCount = hexLine.midRef(1, 2).toInt(nullptr, 16);
        int address = hexLine.midRef(3, 4).toInt(nullptr, 16);
        int recordType = hexLine.midRef(7, 2).toInt(nullptr, 16);

        if (recordType == 0x00) {
            quint32 fullAddress = (extendedLinearAddress & 0xFFFF0000) | address;
            return QByteArray::fromHex(hexLine.midRef(9, byteCount * 2).toLatin1());
        } else if (recordType == 0x04) {
            // 扩展线性地址记录不应该在这里解析数据部分
            return QByteArray();
        } else {
            qWarning() << "非数据记录类型: " << hexLine;
            return QByteArray();
        }
    } else {
        qCritical() << "无效的hex行: " << hexLine;
        return QByteArray();
    }

}
//分包函数的辅助函数（解决地址跳跃问题）
void ProtocolHandler::generatePacketsFromSegment(quint8 station, quint8 sid, quint8 count, const QHash<quint32, QByteArray> &addressDataMap, QList<QByteArray> &packets)
{
    quint32 currentAddress = 0x00000000; // 当前处理的地址

    for (auto it = addressDataMap.begin(); it != addressDataMap.end(); ++it) {
        quint32 segmentAddress = it.key();
        const QByteArray &segmentData = it.value();

        if (currentAddress != (segmentAddress & 0xFFFF0000)) {
            // 如果当前地址与段地址不一致，重置当前地址
            currentAddress = segmentAddress;
        }

        // 生成数据包
        for (int i = 0; i < segmentData.size(); i += count * 2) {
            QByteArray packet;

            // 添加站点号
            packet.append(station);

            // 添加标识符
            packet.append(sid);

            // 添加起始地址 (3字节)
            packet.append((currentAddress >> 16) & 0xFF);
            packet.append((currentAddress >> 8) & 0xFF);
            packet.append(currentAddress & 0xFF);

            // 添加数据长度 (2字节)
            packet.append((count >> 8) & 0xFF);
            packet.append(count & 0xFF);

            // 添加数据部分字节长 (1字节)
            packet.append(count * 2);

            // 添加数据Data
            QByteArray dataSegment = segmentData.mid(i, count * 2);
            if (dataSegment.size() < count * 2) {
                dataSegment.append(QByteArray(count * 2 - dataSegment.size(), 0xFF));
            }
            packet.append(dataSegment);

            // 计算并添加CRC校验码
            unsigned short crc = calculateCRC(packet);
            packet.append(crc & 0xFF);
            packet.append((crc >> 8) & 0xFF);

            // 添加到包列表
            packets.append(packet);
            qDebug()<<"生成数据包"<<packet.toHex();

            // 更新当前地址
            currentAddress += count * 2;
        }
    }
}
